package com.gthncz;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class ConcurrentDemoApp {

    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        ReentrantLock reentrantLock = new ReentrantLock();
        Condition condition = reentrantLock.newCondition();
        try {
            condition.await();
            condition.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

        Semaphore semaphore = new Semaphore(10, true);
        semaphore.acquire(5);
        // do sth.
        semaphore.release(5);

        CountDownLatch countDownLatch = new CountDownLatch(10);
        // countDownLatch.countDown();
        countDownLatch.countDown();

        CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
        // cyclicBarrier.await();
        // do sth.


        // Table: Node<K, V>[].  Node: lock. 其他与 HashMap 的性质一样.
        ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap<>();

        // Table: Entity<K, V>[]. Put: synchronized.
        Hashtable hashtable = new Hashtable();

        HashMap<String, String> hashMap = new HashMap<>();


        // LinkedHashMap 与 HashMap 区别在于, LinkedHashMap 会保存插入的顺序.
        // Entry<K,V> before, after; 双向链表.
        LinkedHashMap<String, String> lruCache = new LinkedHashMap<String, String>(10){

            @Override
            protected boolean removeEldestEntry(Map.Entry eldest) {
                // 改写这部分, 返回是否需要移除
                return this.size() >= 10 + 1;  // 10 是 initialCapacity.
            }

            // thread-safe 的方法
            public synchronized String putCache(String key, String value){
                return this.put(key, value);
            }

        };

        // 就是一个管程. Producer-Consumer Queue.
        ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(10, true);

        // 一种 thread-safe 的 ArrayList. array 是 volatile 类型的, 内部是直接 set/get 的.
        // add: Arrays.copyOf
        CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList();

        //
        ConcurrentSkipListMap skipListMap = new ConcurrentSkipListMap();

        // 没有 recycle node, 因此不存在 ABA 问题. ( 实现依赖 java 的 GC 机制. )
        ConcurrentLinkedQueue concurrentLinkedQueue = new ConcurrentLinkedQueue();

        int NCPUS = Runtime.getRuntime().availableProcessors();

        // threadPool.submit() , Runnable or Callable
        // threadPool.execute(); Runnable

        Executor executor;
        ExecutorService fixedExecutorService = Executors.newFixedThreadPool(NCPUS);
        ExecutorService cachedExecutorService = Executors.newCachedThreadPool();
        ExecutorService singleThreadExecutorService = Executors.newSingleThreadExecutor();
        ExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(NCPUS);
        ExecutorService singleThreadScheduledExecutorService = Executors.newSingleThreadScheduledExecutor();



        ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(NCPUS * 2, true);  // 有界队列
        LinkedBlockingQueue<Runnable> linkedWorkQueue = new LinkedBlockingQueue<>(NCPUS*2); // 无界队列
        SynchronousQueue<Runnable> synchronousWorkQueue = new SynchronousQueue<>(true); // 直接提交
        PriorityBlockingQueue priorityBlockingQueue = new PriorityBlockingQueue(NCPUS);  // 优先级队列

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(NCPUS, NCPUS*2, 1000L, TimeUnit.SECONDS, workQueue);

        /**
         * ThreadLocal 原理
         */
        ThreadLocal<Integer> localId = new ThreadLocal<Integer>() {
            @Override
            protected Integer initialValue() {
                return 0;
            }
        };

        LinkedList<Integer> list;
        Vector<Integer> vector;


        Map.Entry<String, Integer> entry;
        Deque<Integer> stack;
        PriorityQueue<Integer> priorityQueue;
    }

}
